package com.myk.game.shapechesstool;

import androidx.activity.result.ActivityResult;
import androidx.activity.result.ActivityResultCallback;
import androidx.activity.result.ActivityResultLauncher;
import androidx.activity.result.ActivityResultRegistry;
import androidx.activity.result.contract.ActivityResultContract;
import androidx.activity.result.contract.ActivityResultContracts;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;
import androidx.constraintlayout.widget.ConstraintLayout;
import androidx.core.app.ActivityOptionsCompat;

import android.app.Activity;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.Color;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.Bundle;
import android.util.Log;
import android.util.TypedValue;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.TextView;

import com.blankj.utilcode.util.FileIOUtils;
import com.blankj.utilcode.util.FileUtils;
import com.blankj.utilcode.util.GsonUtils;
import com.blankj.utilcode.util.ImageUtils;
import com.blankj.utilcode.util.LogUtils;
import com.blankj.utilcode.util.PathUtils;
import com.blankj.utilcode.util.StringUtils;
import com.blankj.utilcode.util.TimeUtils;
import com.blankj.utilcode.util.ToastUtils;
import com.blankj.utilcode.util.UriUtils;
import com.hjq.permissions.OnPermissionCallback;
import com.hjq.permissions.Permission;
import com.hjq.permissions.XXPermissions;
import com.myk.game.shapechesstool.data.ActionState;
import com.myk.game.shapechesstool.data.SoundData;
import com.myk.game.shapechesstool.dialogs.SettingDialog;
import com.myk.game.shapechesstool.dialogs.ShareDialog;
import com.myk.game.shapechesstool.models.HistoryInfo;
//import com.myk.game.shapechesstool.models.SituationInfo;
import com.myk.game.shapechesstool.utils.FastUtil;
import com.myk.game.shapechesstool.utils.ShareUtil;
import com.myk.game.shapechesstool.utils.StringUtil;
import com.myk.game.shapechesstool.dialogs.BlockingInputDialog;
import com.myk.game.shapechesstool.views.BorderDrawable;
import com.myk.game.shapechesstool.views.ChessBoardView;
import com.myk.game.shapechesstool.views.FlickerTextView;

import java.io.File;
import java.text.SimpleDateFormat;
import java.util.List;
import java.util.Locale;

public class MainActivity extends AppCompatActivity implements IGameUI {

    private ConstraintLayout csl_background;
    private TextView tv_black_name;
    private TextView tv_white_name;
    private ImageView image_black_head;
    private ImageView image_white_head;
    private TextView tv_black_score;
    private TextView tv_white_score;
    private TextView tv_score_symbol;
    private ImageView iv_black_flag;
    private ImageView iv_white_flag;
    private ImageView iv_black_win;
    private ImageView iv_white_win;
    private ChessBoardView chessBoardView;
    private ImageView iv_tool_auto;
    private ImageView iv_tool_force;
    private ImageView iv_tool_delete;
    private ImageView iv_tool_undo;
    private ImageView iv_tool_redo;
    private ImageView iv_tool_share;
    private ImageView iv_tool_records;
    private ImageView iv_tool_setting;
    private FlickerTextView ftv_tip_msg;
    private Drawable toolUsedDrawable;
    private String mRecordPath;
    private String mCurRecordFileName;
    private String mAutoRecordPath;
    private String mAutoRecordFileName;
    private SimpleDateFormat mDateFormat;
    private ActivityResultLauncher<String> recordFileLauncher;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //加载资源
        SoundData.load(this);
        toolUsedDrawable = new BorderDrawable(Color.RED, new int[]{3, 3, 3, 3}, new int[]{20, 20, 20, 20});
        mRecordPath = PathUtils.getExternalAppDataPath() + "/record/";
        mAutoRecordPath = PathUtils.getExternalAppDataPath() + "/auto/";
        mDateFormat = new SimpleDateFormat("yyyy年MM月dd日HH点mm分ss秒", Locale.CHINA);
        mAutoRecordFileName = "auto_record.txt";

        //获取控件引用
        csl_background = findViewById(R.id.csl_background);
        tv_black_name = findViewById(R.id.tv_black_name);
        tv_white_name = findViewById(R.id.tv_white_name);
        image_black_head = findViewById(R.id.image_black_head);
        image_white_head = findViewById(R.id.image_white_head);
        tv_black_score = findViewById(R.id.tv_black_score);
        tv_white_score = findViewById(R.id.tv_white_score);
        tv_score_symbol = findViewById(R.id.tv_score_symbol);
        iv_black_flag = findViewById(R.id.iv_black_flag);
        iv_white_flag = findViewById(R.id.iv_white_flag);
        iv_black_win = findViewById(R.id.iv_black_win);
        iv_white_win = findViewById(R.id.iv_white_win);
        chessBoardView = findViewById(R.id.chess_board_view);
        iv_tool_auto = findViewById(R.id.iv_tool_auto);
        iv_tool_force = findViewById(R.id.iv_tool_force);
        iv_tool_delete = findViewById(R.id.iv_tool_delete);
        iv_tool_undo = findViewById(R.id.iv_tool_undo);
        iv_tool_redo = findViewById(R.id.iv_tool_redo);
        iv_tool_share = findViewById(R.id.iv_tool_share);
        iv_tool_records = findViewById(R.id.iv_tool_records);
        iv_tool_setting = findViewById(R.id.iv_tool_setting);
        ftv_tip_msg = findViewById(R.id.ftv_tip_msg);

        //点击黑方头像切换黑方行动
        image_black_head.setOnClickListener(v -> chessBoardView.changeSide(true));
        //点击白方头像切换白方行动
        image_white_head.setOnClickListener(v -> chessBoardView.changeSide(false));
        //点击黑棋玩家修改名称
        tv_black_name.setOnClickListener(v -> {
            String blackName = new BlockingInputDialog(this, "输入黑棋玩家名称（1-5字符之间）").showDialog().trim();
            chessBoardView.setName(blackName, true);
        });
        //点击白棋玩家修改名称
        tv_white_name.setOnClickListener(v -> {
            String whiteName = new BlockingInputDialog(this, "输入白棋玩家名称（1-5字符之间）").showDialog().trim();
            chessBoardView.setName(whiteName, false);
        });
        //点击黑方分数控件增加黑方分数
        tv_black_score.setOnClickListener(v -> chessBoardView.addScore(true));
        //点击白方分数控件增加白方分数
        tv_white_score.setOnClickListener(v -> chessBoardView.addScore(false));
        //点击恢复自动切换黑白模式
        iv_tool_auto.setOnClickListener(v -> chessBoardView.autoExchange());
        //点击切换为强制持续模式
        iv_tool_force.setOnClickListener(v -> chessBoardView.forceContinue());
        //点击切换为消除模式
        iv_tool_delete.setOnClickListener(v -> chessBoardView.deleteMode());
        //点击返回上一步
        iv_tool_undo.setOnClickListener(v -> chessBoardView.undoOnce());
        //点击撤销返回
        iv_tool_redo.setOnClickListener(v -> chessBoardView.redoOnce());
        //点击分享
        iv_tool_share.setOnClickListener(v -> openShareDialog());
        //点击打开战报管理弹窗
        iv_tool_records.setOnClickListener(v -> openRecordsDialog());
        //点击打开设置弹窗
        iv_tool_setting.setOnClickListener(v -> openSettingDialog());
        //注册从文件管理器中选择文件的回调（用于加载外部的战报文件）
        recordFileLauncher = registerForActivityResult(new ActivityResultContracts.GetContent(), result -> openExternalRecord(UriUtils.uri2File(result)));

        //根据棋盘的大小修复控件的尺寸，以兼容各种不通大小的设备
        chessBoardView.post(() -> {
            float chessBoardWidth = chessBoardView.getWidth();
            tv_black_name.setTextSize(TypedValue.COMPLEX_UNIT_PX, chessBoardWidth / 18f);
            tv_white_name.setTextSize(TypedValue.COMPLEX_UNIT_PX, chessBoardWidth / 18f);
            tv_black_score.setTextSize(TypedValue.COMPLEX_UNIT_PX, chessBoardWidth / 24f);
            tv_white_score.setTextSize(TypedValue.COMPLEX_UNIT_PX, chessBoardWidth / 24f);
            tv_score_symbol.setTextSize(TypedValue.COMPLEX_UNIT_PX, chessBoardWidth / 24f);
            ftv_tip_msg.setTextSize(TypedValue.COMPLEX_UNIT_PX, chessBoardWidth / 24f);
        });

        //初始化棋盘
        chessBoardView.initChessBoard(this, 15, 15, 4, tv_black_name.getText().toString(), tv_white_name.getText().toString());
    }

    //打开分享弹窗
    private void openShareDialog() {
        //打开分享弹窗
        ShareDialog shareDialog = new ShareDialog(this);
        shareDialog.show();
        //截屏分享
        shareDialog.findViewById(R.id.btn_share_pic).setOnClickListener(v13 -> {
            String shotPath = PathUtils.getExternalAppDataPath() + File.separator + "shot";
            FileUtils.createOrExistsDir(shotPath);
            FileUtils.deleteAllInDir(shotPath);//每次截图都先清空以免内存占太多
            SimpleDateFormat format = new SimpleDateFormat("yyyyMMddHHmmss", Locale.getDefault());
            String filePath = shotPath + File.separator + TimeUtils.getNowString(format) + ".jpg";

            new Thread(() -> {
                try {
                    Bitmap bitmap = shotChessBoard();
                    if (ImageUtils.save(bitmap, filePath, Bitmap.CompressFormat.JPEG)) {
                        File bitmapFile = new File(filePath);
                        if (FileUtils.isFileExists(bitmapFile)) {
                            runOnUiThread(() -> ShareUtil.shareFile(MainActivity.this, bitmapFile));
                        }
                        else {
                            toast("分享失败！");
                        }
                    }
                    else {
                        toast("分享失败！");
                    }
                }
                catch (Exception e) {
                    LogUtils.e("视图截屏发生异常->" + e.toString());
                    toast("分享失败！");
                }
            }).start();

            shareDialog.dismiss();
        });
        //分享对局战报
        shareDialog.findViewById(R.id.btn_share_record).setOnClickListener(v12 -> {
            if (StringUtils.isEmpty(mCurRecordFileName)) {
                createNewRecord();
            }
            File recordFile = new File(mRecordPath + mCurRecordFileName);
            if (FileUtils.isFileExists(recordFile)) {
                runOnUiThread(() -> ShareUtil.shareFile(MainActivity.this, recordFile));
            }
            else {
                toast("分享失败！");
            }
        });
    }

    //对棋盘控件及状态提示控件截图
    private Bitmap shotChessBoard() {
        Bitmap srcBmp = ImageUtils.view2Bitmap(csl_background);
        float width = csl_background.getWidth();
        float height = width * 7 / 6f; //xml界面里定死了棋盘控件加上状态提示栏的大小比例
        Bitmap clipBmp = ImageUtils.clip(srcBmp, 0, 0, (int) width, (int) height);
        return ImageUtils.compressByScale(clipBmp, 600, 700); //缩放成固定大小
    }

    //打开战报管理弹窗
    private void openRecordsDialog() {
        List<File> recordFiles = FileUtils.listFilesInDir(mRecordPath);
        String[] fileNames = new String[recordFiles.size()];
        for (int i = 0; i < recordFiles.size(); i++) {
            File recordFile = recordFiles.get(i);
            fileNames[i] = recordFile.getName() + " (" + FileUtils.getSize(recordFile) + ")";
        }
        if (StringUtils.isEmpty(mCurRecordFileName)) {
            new AlertDialog.Builder(this)
                    .setTitle("形棋对局战报列表")
                    .setItems(fileNames, (dialog, which) -> openSelectRecord(recordFiles, which))
                    .setNeutralButton("清空", (dialog14, which14) -> clearAllRecords(recordFiles))
                    .setNegativeButton("新建", (dialog, which) -> createNewRecord())
                    .show();
        }
        else {
            AlertDialog recordsDialog = new AlertDialog.Builder(this)
                    .setTitle("形棋对局战报列表")
                    .setAdapter(new ArrayAdapter<CharSequence>(this, android.R.layout.simple_list_item_1, fileNames) {
                        @NonNull
                        @Override
                        public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) {
                            View view = super.getView(position, convertView, parent);
                            TextView textView = view.findViewById(android.R.id.text1);
                            String itemValue = (String) getItem(position);
                            String itemFileName = itemValue.substring(0, mCurRecordFileName.length());
                            if (itemFileName.equals(mCurRecordFileName)) {
                                textView.setTextColor(Color.RED);  //战报列表中当前记录的一项要高亮显示
                            }
                            else {
                                textView.setTextColor(Color.BLACK);
                            }
                            return view;
                        }
                    }, (dialog, which) -> openSelectRecord(recordFiles, which))
                    .setNeutralButton("清空", (dialog14, which14) -> clearAllRecords(recordFiles))
                    .setNegativeButton("新建", (dialog, which) -> createNewRecord())
                    .setPositiveButton("更新", (dialog, which) -> updateOldRecord())
                    .create();
            recordsDialog.show();
        }
    }

    //打开设置弹窗
    private void openSettingDialog() {
        SettingDialog settingDialog = new SettingDialog(this);
        settingDialog.show();
        //根据设置创建棋盘
        EditText edtBoardCol = settingDialog.findViewById(R.id.edt_board_col);
        EditText edtBoardRow = settingDialog.findViewById(R.id.edt_board_row);
        EditText edtMaxScore = settingDialog.findViewById(R.id.edt_max_score);
        Button btnNewBoard = settingDialog.findViewById(R.id.btn_new_board);
        /*Button btnLoadClip = settingDialog.findViewById(R.id.btn_load_clip);*/
        Button btnRestoreHistory = settingDialog.findViewById(R.id.btn_restore_history);
        Button btnLoadFile = settingDialog.findViewById(R.id.btn_load_file);
        //根据设置创建新棋盘
        btnNewBoard.setOnClickListener(v1 -> {
            int boardCol = Integer.parseInt(edtBoardCol.getText().toString());
            int boardRow = Integer.parseInt(edtBoardRow.getText().toString());
            int maxScore = Integer.parseInt(edtMaxScore.getText().toString());
            mCurRecordFileName = null; //别忘了这个也要置空
            chessBoardView.initChessBoard(this, boardCol, boardRow, maxScore, "黑棋", "白棋");
            settingDialog.dismiss();
        });
        /*//根据剪贴版还原棋盘
        btnLoadClip.setOnClickListener(v14 -> {
            //读取剪贴板
            String sharedSituationJson = ClipboardUtils.getText().toString();
            if (!StringUtils.isEmpty(sharedSituationJson)) {
                try {
                    SituationInfo situationInfo = GsonUtils.fromJson(sharedSituationJson, SituationInfo.class);
                    if (situationInfo != null) {
                        mCurRecordFileName = null; //置空该路径以免保存错误的战报
                        chessBoardView.restoreSituation(this, situationInfo);
                        settingDialog.dismiss();
                        clearMsg();
                        printlnMsg("从剪贴板中还原局面");
                        toast("已从剪贴板中还原局面");
                    }
                    else {
                        toast("剪切板中的数据非局面报文");
                    }
                }
                catch (Exception e) {
                    e.printStackTrace();
                    toast("还原局面出错！");
                }
            }
            else {
                toast("剪切板中无数据");
            }
        });*/
        //恢复上局历史记录
        btnRestoreHistory.setOnClickListener(v15 -> {
            try {
                File autoRecordFile = FileUtils.getFileByPath(mAutoRecordPath + mAutoRecordFileName);
                if (FileUtils.isFileExists(autoRecordFile)) {
                    String autoRecordData = FileIOUtils.readFile2String(autoRecordFile);
                    if (!StringUtils.isEmpty(autoRecordData)) {
                        String uzipRecordData = StringUtil.uncompress(autoRecordData); //解压缩
                        List<String> historyJsonList = GsonUtils.fromJson(uzipRecordData, GsonUtils.getListType(String.class)); //解析为历史记录集合
                        String historyJson = historyJsonList.get(historyJsonList.size() - 1); //获取最近的历史记录
                        HistoryInfo curHistory = GsonUtils.fromJson(historyJson, HistoryInfo.class); //获取最近的历史记录//ChessBoardView中是这样存取的确保一致
                        chessBoardView.restoreExternalHistory(this, curHistory);
                        chessBoardView.setHistoryList(historyJsonList);
                        mCurRecordFileName = null; //还原历史记录置空这个路径以免战报保存错误，因为自动保存的记录文件不该手动管理
                        settingDialog.dismiss();
                        clearMsg();
                        printlnMsg("从历史记录中还原棋盘");
                        toast("已恢复上局历史记录");
                    }
                    else {
                        toast("无历史记录");
                    }
                }
                else {
                    toast("无历史记录");
                }
            }
            catch (Exception e) {
                e.printStackTrace();
                toast("恢复历史记录出错！");
            }
        });
        //加载外部战报文件
        btnLoadFile.setOnClickListener(v22 -> requestPermission(() -> {
            recordFileLauncher.launch("text/plain");
            settingDialog.dismiss();
        }));
    }

    //打开选择的外部战报
    private void openExternalRecord(File recordFile) {
        new Thread(() -> {
            try {
                String recordData = FileIOUtils.readFile2String(recordFile); //获取战报数据（压缩的）
                String uzipRecordData = StringUtil.uncompress(recordData); //解压缩
                List<String> historyJsonList = GsonUtils.fromJson(uzipRecordData, GsonUtils.getListType(String.class)); //解析为历史记录集合
                String historyJson = historyJsonList.get(historyJsonList.size() - 1); //获取最近的历史记录
                HistoryInfo curHistory = GsonUtils.fromJson(historyJson, HistoryInfo.class); //获取最近的历史记录//ChessBoardView中是这样存取的确保一致
                runOnUiThread(() -> new AlertDialog.Builder(this)
                        .setTitle("如何处理该战报？")
                        .setMessage("文件名称：" + recordFile.getName() + "\n" +
                                "更新时间：" + TimeUtils.millis2String(recordFile.lastModified(), mDateFormat) + "\n" +
                                "文件大小：" + FileUtils.getSize(recordFile) + "\n" +
                                "棋盘大小：" + curHistory.getCol() + "列" + curHistory.getRow() + "行\n" +
                                "获胜分数：" + curHistory.getMaxScore() + "分\n" +
                                "双方名称：" + "黑方“" + curHistory.getBlackName() + "”，" + "白方“" + curHistory.getWhiteName() + "”" + "\n" +
                                "当前比分：" + "黑方" + curHistory.getBlackScore() + "分，" + "白方" + curHistory.getWhiteScore() + "分\n" +
                                "回合数：" + historyJsonList.size() + "\n" +
                                "当前状态：" + curHistory.getActionState().tip)
                        .setCancelable(true)
                        .setPositiveButton("导入棋盘", (dialog12, which12) -> {
                            chessBoardView.restoreExternalHistory(this, curHistory);
                            chessBoardView.setHistoryList(historyJsonList);
                            mCurRecordFileName = null;
                            clearMsg();
                            printlnMsg("从外部战报中还原棋盘");
                            toast("已加载外部战报历史");
                            dialog12.dismiss();
                        })
                        .show());
            }
            catch (Exception e) {
                e.printStackTrace();
                toast("打开战报出错！");
            }
        }).start();
    }

    //更新旧战报
    private void updateOldRecord() {
        String fileName = mCurRecordFileName;
        String recordJson = GsonUtils.toJson(chessBoardView.getHistoryList()); //历史记录集合转成json
        String zipRecordJson = StringUtil.compress(recordJson); //压缩字符串
        FileUtils.createOrExistsDir(mRecordPath); //确保文件夹存在
        FileUtils.createOrExistsFile(mRecordPath + fileName); //确保文件存在
        boolean saveSuccess = FileIOUtils.writeFileFromString(mRecordPath + fileName, zipRecordJson); //存储战报到本地文件
        if (saveSuccess) {
            toast("战报更新成功！");
        }
        else {
            toast("战报保存失败！");
        }
    }

    //创建新战报
    private void createNewRecord() {
        String preRecordName = tv_black_name.getText().toString().trim() + "vs" + tv_white_name.getText(); //默认填充名字
        String recordName = new BlockingInputDialog(this, "输入战报名称", preRecordName).showDialog().trim(); //阻塞弹窗获取自定义战报名称
        String fileName = recordName + "(" + TimeUtils.getNowString(mDateFormat) + ")" + ".txt"; //拼接日期获取完整文件名称
        String recordJson = GsonUtils.toJson(chessBoardView.getHistoryList()); //历史记录集合转成json
        String zipRecordJson = StringUtil.compress(recordJson); //压缩字符串
        FileUtils.createOrExistsDir(mRecordPath); //确保文件夹存在
        boolean saveSuccess = FileIOUtils.writeFileFromString(mRecordPath + fileName, zipRecordJson); //存储战报到本地文件
        if (saveSuccess) {
            mCurRecordFileName = fileName;
            toast("战报保存成功！");
        }
        else {
            toast("战报保存失败！");
        }
    }

    //打开选择的战报
    private void openSelectRecord(List<File> recordFiles, int which) {
        new Thread(() -> {
            try {
                File recordFile = recordFiles.get(which); //选取的战报文件
                String recordData = FileIOUtils.readFile2String(recordFile); //获取战报数据（压缩的）
                String uzipRecordData = StringUtil.uncompress(recordData); //解压缩
                List<String> historyJsonList = GsonUtils.fromJson(uzipRecordData, GsonUtils.getListType(String.class)); //解析为历史记录集合
                String historyJson = historyJsonList.get(historyJsonList.size() - 1); //获取最近的历史记录
                HistoryInfo curHistory = GsonUtils.fromJson(historyJson, HistoryInfo.class); //获取最近的历史记录//ChessBoardView中是这样存取的确保一致
                runOnUiThread(() -> new AlertDialog.Builder(this)
                        .setTitle("如何处理该战报？")
                        .setMessage("文件名称：" + recordFile.getName() + "\n" +
                                "更新时间：" + TimeUtils.millis2String(recordFile.lastModified(), mDateFormat) + "\n" +
                                "文件大小：" + FileUtils.getSize(recordFile) + "\n" +
                                "棋盘大小：" + curHistory.getCol() + "列" + curHistory.getRow() + "行\n" +
                                "获胜分数：" + curHistory.getMaxScore() + "分\n" +
                                "双方名称：" + "黑方“" + curHistory.getBlackName() + "”，" + "白方“" + curHistory.getWhiteName() + "”" + "\n" +
                                "当前比分：" + "黑方" + curHistory.getBlackScore() + "分，" + "白方" + curHistory.getWhiteScore() + "分\n" +
                                "回合数：" + historyJsonList.size() + "\n" +
                                "当前状态：" + curHistory.getActionState().tip)
                        .setCancelable(true)
                        .setNeutralButton("删除", (dialog14, which14) -> new AlertDialog.Builder(this)
                                .setMessage("是否删除该战报？")
                                .setNegativeButton("取消", (dialog16, which16) -> dialog16.dismiss())
                                .setPositiveButton("确定", (dialog15, which15) -> {
                                    FileUtils.delete(recordFile);
                                    mCurRecordFileName = null; //删除了战报就不要能够更新了
                                })
                                .show())
                        .setNegativeButton("分享", (dialog13, which13) -> ShareUtil.shareFile(this, recordFile))
                        .setPositiveButton("导入棋盘", (dialog12, which12) -> {
                            chessBoardView.restoreExternalHistory(this, curHistory);
                            chessBoardView.setHistoryList(historyJsonList);
                            mCurRecordFileName = recordFile.getName();
                            clearMsg();
                            printlnMsg("从战报中还原棋盘");
                            toast("已加载战报历史");
                            dialog12.dismiss();
                        })
                        .show());
            }
            catch (Exception e) {
                e.printStackTrace();
                toast("打开战报出错！");
            }
        }).start();
    }

    //清空所有战报
    private void clearAllRecords(List<File> recordFiles) {
        new AlertDialog.Builder(this)
                .setMessage("是否清空战报？")
                .setNegativeButton("取消", (dialog16, which16) -> dialog16.dismiss())
                .setPositiveButton("确定", (dialog15, which15) -> {
                    for (File logFile : recordFiles) {
                        FileUtils.delete(logFile);
                    }
                    mCurRecordFileName = null; //清空了战报这个记录也清空
                    dialog15.dismiss();
                })
                .show();
    }

    //请求权限
    private void requestPermission(Runnable successCallback) {
        if (XXPermissions.isGranted(this, Permission.READ_EXTERNAL_STORAGE)) {
            successCallback.run();
        }
        else {
            XXPermissions.with(this).permission(Permission.READ_EXTERNAL_STORAGE)
                    .request(new OnPermissionCallback() {

                        @Override
                        public void onGranted(@NonNull List<String> permissions, boolean allGranted) {
                            if (!allGranted) {
                                toast("获取部分权限成功，但部分权限未正常授予");
                                return;
                            }
                            toast("获取权限成功");
                            successCallback.run();
                        }

                        @Override
                        public void onDenied(@NonNull List<String> permissions, boolean doNotAskAgain) {
                            if (doNotAskAgain) {
                                toast("被永久拒绝授权，请手动授予权限");
                                XXPermissions.startPermissionActivity(MainActivity.this, permissions);
                            }
                            else {
                                toast("获取权限失败");
                            }
                        }
                    });
        }
    }

    @Override
    protected void onPause() {
        super.onPause();
        //自动保存历史记录用于下次打开时还原，该记录不会进入战报管理列表
        new Thread(() -> {
            List<String> historyList = chessBoardView.getHistoryList();
            if (historyList.size() > 1) { //确实有行动了才保存历史
                String recordJson = GsonUtils.toJson(historyList); //历史记录集合转成json
                String zipRecordJson = StringUtil.compress(recordJson); //压缩字符串
                FileUtils.createOrExistsDir(mAutoRecordPath); //确保文件夹存在
                String filePath = mAutoRecordPath + mAutoRecordFileName; //自动保存战报的路径
                FileIOUtils.writeFileFromString(filePath, zipRecordJson); //存储战报到本地文件
            }
        }).start();
    }

    @Override
    public void onBackPressed() {
        if (!FastUtil.isFast("onBackPressed", 2000)) {
            new AlertDialog.Builder(this)
                    .setTitle("是否退出程序？")
                    .setCancelable(true)
                    .setNegativeButton("取消", (dialog13, which13) -> {

                    })
                    .setPositiveButton("退出", (dialog12, which12) -> {
                        finish();
                    })
                    .show();
        }
    }

    @Override
    public void refreshUI(ActionState state, String blackName, String whiteName, int blackScore, int whiteScore) {
        //显示名称
        tv_black_name.setText(blackName);
        tv_white_name.setText(whiteName);
        //显示分数
        tv_black_score.setText(blackScore + "分");
        tv_white_score.setText(whiteScore + "分");
        //显示行动方
        if (state == ActionState.WAIT_FALL_BLACK || state == ActionState.THEN_MOVE_BLACK || state == ActionState.PUSH_AWAY_WHITE || state == ActionState.ENFORCE_BLACK) {
            iv_black_flag.setVisibility(View.VISIBLE);
            iv_white_flag.setVisibility(View.GONE);
        }
        else if (state == ActionState.WAIT_FALL_WHITE || state == ActionState.THEN_MOVE_WHITE || state == ActionState.PUSH_AWAY_BLACK || state == ActionState.ENFORCE_WHITE) {
            iv_black_flag.setVisibility(View.GONE);
            iv_white_flag.setVisibility(View.VISIBLE);
        }
        else {
            iv_black_flag.setVisibility(View.GONE);
            iv_white_flag.setVisibility(View.GONE);
        }
        //显示获胜方
        if (state == ActionState.BLACK_WIN) {
            iv_black_win.setVisibility(View.VISIBLE);
            iv_white_win.setVisibility(View.GONE);
        }
        else if (state == ActionState.WHITE_WIN) {
            iv_black_win.setVisibility(View.GONE);
            iv_white_win.setVisibility(View.VISIBLE);
        }
        else {
            iv_black_win.setVisibility(View.GONE);
            iv_white_win.setVisibility(View.GONE);
        }
        //显示工具按钮常量
        if (state == ActionState.WAIT_FALL_BLACK || state == ActionState.THEN_MOVE_BLACK || state == ActionState.PUSH_AWAY_WHITE || state == ActionState.WAIT_FALL_WHITE || state == ActionState.THEN_MOVE_WHITE || state == ActionState.PUSH_AWAY_BLACK) {
            iv_tool_auto.setBackground(toolUsedDrawable);
            iv_tool_force.setBackground(null);
            iv_tool_delete.setBackground(null);
        }
        else if (state == ActionState.ENFORCE_BLACK || state == ActionState.ENFORCE_WHITE) {
            iv_tool_auto.setBackground(null);
            iv_tool_force.setBackground(toolUsedDrawable);
            iv_tool_delete.setBackground(null);
        }
        else if (state == ActionState.CONTINUE_DELETE) {
            iv_tool_auto.setBackground(null);
            iv_tool_force.setBackground(null);
            iv_tool_delete.setBackground(toolUsedDrawable);
        }
        //显示操作提示
        ftv_tip_msg.setText(state.tip);
    }

    @Override
    public void playSound(int type) {
        SoundData.play(type);
    }

    @Override
    public void playSound(int type, int freq) {
        SoundData.play(type, freq, 1);
    }

    @Override
    public void setTip(String tipMsg) {
        ftv_tip_msg.setText(tipMsg);
    }

    @Override
    public void printMsg(String msg) {

    }

    @Override
    public void printlnMsg(String msg) {

    }

    @Override
    public void clearMsg() {

    }

    @Override
    public void toast(String text) {
        ToastUtils.showShort(text);
    }

}